package org.cybzacg.convert.enums;

import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.function.Predicate;

/**
 * 字段过滤策略枚举
 * 定义属性拷贝时的字段过滤规则和策略
 * 
 * @author PropertyCopier Implementation
 * @version 1.0.0
 */
public enum FieldFilterStrategy {
    /**
     * 只包含指定字段策略
     * 只有在包含列表中的字段才会被拷贝
     */
    INCLUDE_ONLY("include_only", "只包含指定字段", 
        (fields, included, excluded) -> fields.stream()
            .filter(field -> included.contains(field.getName()))
            .toList()),
    
    /**
     * 排除指定字段策略
     * 除了在排除列表中的字段，其他字段都会被拷贝
     */
    EXCLUDE("exclude", "排除指定字段",
        (fields, included, excluded) -> fields.stream()
            .filter(field -> !excluded.contains(field.getName()))
            .toList()),
    
    /**
     * 基于注解过滤策略
     * 根据字段上标注的注解来决定是否拷贝
     */
    ANNOTATION_BASED("annotation_based", "基于注解过滤",
        (fields, included, excluded) -> {
            // 注解过滤逻辑在具体实现中处理
            return fields;
        }),
    
    /**
     * 基于命名模式过滤策略
     * 根据字段名称的匹配模式来决定是否拷贝
     */
    PATTERN_BASED("pattern_based", "基于命名模式过滤",
        (fields, included, excluded) -> {
            // 模式过滤逻辑在具体实现中处理
            return fields;
        });

    private final String code;
    private final String description;
    private final FieldFilter filterFunction;

    FieldFilterStrategy(String code, String description, FieldFilter filterFunction) {
        this.code = code;
        this.description = description;
        this.filterFunction = filterFunction;
    }

    /**
     * 获取策略代码
     * 
     * @return 策略代码
     */
    public String getCode() {
        return code;
    }

    /**
     * 获取策略描述
     * 
     * @return 策略描述
     */
    public String getDescription() {
        return description;
    }

    /**
     * 根据代码获取过滤策略
     * 
     * @param code 策略代码
     * @return 对应的过滤策略，如果未找到则返回INCLUDE_ONLY
     */
    public static FieldFilterStrategy fromCode(String code) {
        if (code == null) {
            return INCLUDE_ONLY;
        }
        
        for (FieldFilterStrategy strategy : values()) {
            if (strategy.code.equalsIgnoreCase(code.trim())) {
                return strategy;
            }
        }
        
        return INCLUDE_ONLY;
    }

    /**
     * 验证过滤策略是否有效
     * 
     * @param strategy 要验证的策略
     * @return 如果策略有效则返回true
     */
    public static boolean isValid(FieldFilterStrategy strategy) {
        return strategy != null;
    }

    /**
     * 检查策略是否需要字段列表配置
     * 
     * @return 如果需要字段列表配置则返回true
     */
    public boolean requiresFieldList() {
        return this == INCLUDE_ONLY || this == EXCLUDE;
    }

    /**
     * 检查策略是否需要注解配置
     * 
     * @return 如果需要注解配置则返回true
     */
    public boolean requiresAnnotationConfig() {
        return this == ANNOTATION_BASED;
    }

    /**
     * 检查策略是否需要模式配置
     * 
     * @return 如果需要模式配置则返回true
     */
    public boolean requiresPatternConfig() {
        return this == PATTERN_BASED;
    }

    /**
     * 应用字段过滤
     * 
     * @param fields 所有字段列表
     * @param includedFields 包含字段集合
     * @param excludedFields 排除字段集合
     * @return 过滤后的字段列表
     */
    public java.util.List<java.lang.reflect.Field> applyFilter(
            java.util.List<java.lang.reflect.Field> fields,
            Set<String> includedFields,
            Set<String> excludedFields) {
        if (fields == null) {
            return java.util.Collections.emptyList();
        }
        
        Set<String> included = includedFields != null ? includedFields : new HashSet<>();
        Set<String> excluded = excludedFields != null ? excludedFields : new HashSet<>();
        
        return filterFunction.filter(fields, included, excluded);
    }

    /**
     * 获取默认配置
     * 
     * @return 默认的字段集合配置
     */
    public Set<String> getDefaultFields() {
        switch (this) {
            case INCLUDE_ONLY:
                return new HashSet<>();
            case EXCLUDE:
                return new HashSet<>(Arrays.asList("id", "createTime", "updateTime"));
            default:
                return new HashSet<>();
        }
    }

    @Override
    public String toString() {
        return String.format("%s (%s)", description, code);
    }

    /**
     * 字段过滤函数接口
     */
    @FunctionalInterface
    private interface FieldFilter {
        java.util.List<java.lang.reflect.Field> filter(
            java.util.List<java.lang.reflect.Field> fields,
            Set<String> includedFields,
            Set<String> excludedFields);
    }
}
